"use strict";

const path = require("path");
const Package = require("@luo-cli-dev/package");
const log = require("@luo-cli-dev/log");
const { exec: spawn } = require('@luo-cli-dev/utils');


const SETTINGS = {
  init: "@luo-cli-dev/init",
  publish: "@luo-cli-dev/publish",
};

const CACHE_DIR = "dependencies";

async function exec() {
  console.log("exec");
  // 1.targetPath 拿到modulePath
  // 2.modulePath 拿到Package(npm模块 如init,other-init)
  // 3.Package.getRootFile拿到模块入口文件进行使用
  // 将初始化模块分为一个一个Package,Package可以进行一定的封装
  // const p = new Package()
  // 调试命令：luo-cli-dev init --targetPath /Users/bruceluo/Desktop/Developer/luo-cli-dev/luo-cli-dev/commands/init --debug test-project --force
  let targetPath = process.env.CLI_TARGET_PATH;
  const homePath = process.env.CLI_HOME_PATH;
  let storeDir = "";
  let pkg;
  log.verbose("targetPath", targetPath);
  log.verbose("homePath", homePath);

  const cmdObj = arguments[arguments.length - 1];
  const cmdName = cmdObj.name(); // init or publish
  const packageName = SETTINGS[cmdName];
  const packageVersion = "latest";

  // luo-cli-dev init 没有指定路径
  if (!targetPath) {
    targetPath = path.resolve(homePath, CACHE_DIR); // 生成缓存路径
    storeDir = path.resolve(targetPath, "node_modules");
    log.verbose("targetPath", targetPath);
    log.verbose("storeDir", storeDir);
    pkg = new Package({
      targetPath,
      storeDir,
      packageName,
      packageVersion,
    });
    if (await pkg.exists()) {
      // 更新package
      await pkg.update();
    } else {
      // 安装package
      await pkg.install();
      console.log("安装");
    }
    console.log(await pkg.exists());
  } else {
    pkg = new Package({
      targetPath,
      packageName,
      packageVersion,
    });
  }

  // 模块安装好后拿到rootFile（也就是对应的初始化模块）执行
  const rootFile = pkg.getRootFilePath();
  // 目前这里是在当前进程中调用，这样无法充分使用cpu资源
  // if (rootFile) require(rootFile).apply(null, arguments);
  // 下一步是把他改着成在子进程中调用，以便利用好cpu资源，child_process
  if (rootFile) {
    try {
      // 在当前进程中调用
      // require(rootFile).call(null, Array.from(arguments));
      // 在node子进程中调用
      const args = Array.from(arguments);
      const cmd = args[args.length - 1];
      const o = Object.create(null);
      Object.keys(cmd).forEach(key => {
        if (cmd.hasOwnProperty(key) &&
          !key.startsWith('_') &&
          key !== 'parent') {
          o[key] = cmd[key];
        }
      });
      args[args.length - 1] = o;
      const code = `require('${rootFile}').call(null, ${JSON.stringify(args)})`;
      log.info('脚手架根路径',code)
      // 使用child_process.spawn子进程执行code
      const child = spawn('node', ['-e', code], {
        cwd: process.cwd(),
        stdio: 'inherit', // 所有输出流输入到当前子进程中
      });
      child.on('error', e => {
        log.error(e.message);
        process.exit(1);
      });
      child.on('exit', e => {
        log.verbose('命令执行成功:' + e);
        process.exit(e);
      });
    } catch (e) {
      log.error(e.message);
    }
  }
}

module.exports = exec;
